#ifndef AABBCUH
#define AABBCUH
#include"raytracingtool.cuh"
#include<thrust/swap.h>
#define __duel__ __host__ __device__
class aabb
{
public:
    __duel__ void DisInfo()
    {
        printf("min= ");
        _min.DisInfo();
        printf("max= ");
        _max.DisInfo();
    };
    __duel__ aabb() {}
    __duel__ aabb(const vec3& a, const vec3& b) { _min = a; _max = b;}

    __duel__ vec3 min() const {return _min; }
    __duel__ vec3 max() const {return _max; }
                //tmin tmax 射线的t
    __device__ bool hit(const ray& r, float tmin, float tmax) const 
    {
        for (int a = 0; a < 3; a++) 
        {
            float invD = 1.0f / r.direction()[a];
            float t0 = (min()[a] - r.origin()[a]) * invD;
            float t1 = (max()[a] - r.origin()[a]) * invD;
            if (invD < 0.0f)
                thrust::swap(t0, t1);
            tmin = t0 > tmin ? t0 : tmin;
            tmax = t1 < tmax ? t1 : tmax;
            if (tmax <= tmin)
                return false;
        }
        return true;
        // for(int a=0;a<3;a++)
        // {
        //     float invD = 1.0f / r.direction()[a];
        //     float t0=ffmin((_min[a]-r.origin()[a]),
        //                     (_max[a]-r.origin()[a]));
        //     float t1=ffmax((_min[a] - r.origin()[a]),
        //                     (_max[a] - r.origin()[a]));
            
        //     tmin = ffmax(t0, tmin);
        //     tmax = ffmin(t1, tmax);
        //     if (tmax <= tmin)
        //         return false;
        // }
        // return true;
    }

    vec3 _min;
    vec3 _max;

};
__device__ bool hitaabb(const ray& r, float tmin, float tmax,aabb&ab)  
{
    for (int a = 0; a < 3; a++) 
    {
        float invD = 1.0f / r.direction()[a];
        float t0 = (ab.min()[a] - r.origin()[a]) * invD;
        float t1 = (ab.max()[a] - r.origin()[a]) * invD;
        if (invD < 0.0f)
            thrust::swap(t0, t1);
        tmin = t0 > tmin ? t0 : tmin;
        tmax = t1 < tmax ? t1 : tmax;
        if (tmax <= tmin)
            return false;
    }
    return true;
        
}
__duel__ aabb surrounding_box(aabb box0, aabb box1) 
{
    
    vec3 mysmall(ffmin(box0.min().x(), box1.min().x()),
               ffmin(box0.min().y(), box1.min().y()),
               ffmin(box0.min().z(), box1.min().z()));
    vec3 mybig  (ffmax(box0.max().x(), box1.max().x()),
               ffmax(box0.max().y(), box1.max().y()),
               ffmax(box0.max().z(), box1.max().z()));
    return aabb(mysmall,mybig);
}

#endif